--
-- Author: shunguo.chen
-- Date: 2016-06-20 12:38:27
--
-- FriendModel

local Friend = require("app.public.dao.Friend")

local fileName = string.getModeName(...)
local ClassRef = class(fileName, app.mvc.ModelBase)

local QUERY_PER_NUM = 5
local REQUEST_CDTIME = 2 -- 请求CD时间

function ClassRef:ctor(data)
	self.super.ctor(self, data)
end

function ClassRef:init()
	self._friends = nil
	self._blacks = nil
	self._recents = nil
	self._requests = nil

	self._recommends = nil 	-- 推荐缓存
	self._nears = nil 		--附近缓存

	self._recommendTime = nil 	-- 推荐缓存时间
	self._nearTime = nil 		-- 附近缓存时间
end

function ClassRef:initData()
	-- print("FriendModel:initData()")
	-- self:getFriends()
	-- self:getBlacks()
end

function ClassRef:_sortFriends(list)
	if #list > 0 then
		table.sort(list, function(a, b)
			if a.online == b.online then
				if a.level == b.level then
					return a.uid < b.uid
				else
					return a.level > b.level
				end
			else
				return a.online
			end
		end)
	end
end

function ClassRef:getFriends()
	if self._friends == nil then
		self._friends = {}
		for k, v in pairs(UD.friends) do
			table.insert(self._friends, v)
		end
		self:_sortFriends(self._friends)
	end
	return self._friends
end

function ClassRef:getOnlineFriends()
	self:getFriends()
	local ret = {}
	for i,v in ipairs(self._friends) do
		local isInMyTeam = app:sendMsg("TeamModel", "isInTeam", v.uid)
		if v.online and not isInMyTeam then
			table.insert(ret, v)
		end
	end
	return ret
end

function ClassRef:getRequests()
	return self._requests or {}
end

function ClassRef:isInRequestList(uid)
	if not self._requests then return false end

	for _, v in ipairs(self._requests) do
		if v.info.uid == uid then return true end
	end
	return false
end

function ClassRef:addFriendRequest(info)
	-- 右下角的通知
	local params = {
		remindId = Constant.FUNC_TYPE_ADD_FRIEND,
		dataTemp = {uid = info.uid, name = info.name}
	}
	local desktopController = UIHandler:getDesktopController()
	if desktopController then
		desktopController:insertFourthTips( params )
	end

	-- 添加到申请列表里
	if not self._requests then return end

	local isIn = self:isInRequestList(info.uid)
	if not isIn then
		local vo = Friend.new({userBaseInfo = info, online = true}, Enums.FriendType.apply)
		table.insert(self._requests, vo)
	end
end

function ClassRef:removeFriendRequest(uid)
	if not self._requests then return end

	for i = #self._requests, 1, -1 do
		local vo = self._requests[i]
		if vo.info.uid == uid then
			table.remove(self._requests, i)
		end
	end
end

function ClassRef:getBlacks()
	if self._blacks == nil then
		self._blacks = {}
		for k, v in pairs(UD.blacks) do
			table.insert(self._blacks, v)
		end
		self:_sortFriends(self._blacks)
	end
	return self._blacks
end

function ClassRef:getRecents()
	if self._recents == nil then
		self:reqRecentList()
	end
	return self._recents or {}
end
function ClassRef:clearRecents()
	-- print("FriendModel.clearRecents")
	self._recents = nil
end

-- idx = 1 	附近
-- idx = 2 	推荐
-- idx = 3 	队友（最近组过队的人）
function ClassRef:getSearchs(idx)
	local ret
	if idx == 1 then
		local nearbyUsers = FieldManager:getNearbyUserNotInTeam()
		if nearbyUsers then
			ret = {}
			for _, v in pairs(nearbyUsers) do
				if not UD:isFriend(v.uid) and not UD:isBlack(v.uid) then
					local data = {userBaseInfo=v, online=true}
					local vo = Friend.new(data, Enums.FriendType.stranger)
					ret[#ret + 1] = vo
				end
			end
			-- if self._nearTime and (app:getTime() - self._nearTime) <= REQUEST_CDTIME then
			-- 	ret = self._nears
			-- else
			-- 	self:reqSearchNearbyUser()
			-- end
			self:_sortFriends(ret)
		end
	elseif idx == 2 then
		if self._recommendTime and (app:getTime() - self._recommendTime) <= REQUEST_CDTIME then
			ret = self._recommends
		else
			self:reqRecommendFriend()
		end
	elseif idx == 3 then
		ret = self:getRecents()
	end
	return ret or {}
end

function ClassRef:updateFriends(uid, friend, opt)
	if self._friends == nil then return end
	if opt == "insert" then
		table.insert(self._friends, friend)
		self:_sortFriends(self._friends)
	elseif opt == "update" then

	elseif opt == "delete" then
		for i, v in ipairs(self._friends) do
			if v.uid == uid then
				table.remove(self._friends, i)
				break
			end
		end
	end
	app:sendMsg("FriendController", "updateFriendList", opt, friend)
end

function ClassRef:updateBlacks(uid, black, opt)
	if self._blacks == nil then return end
	if opt == "insert" then
		table.insert(self._blacks, black)
		self:_sortFriends(self._blacks)
	elseif opt == "update" then

	elseif opt == "delete" then
		for i, v in ipairs(self._blacks) do
			if v.uid == uid then
				table.remove(self._blacks, i)
				break
			end
		end
	end
	app:sendMsg("FriendController", "updateBlackList", opt, black)
end

function ClassRef:updateSearch(users)
	users = users or {}
	local rets = {}
	if #users > 0 then
		for i,v in ipairs(users) do
			local vo = Friend.new(v, Enums.FriendType.stranger)
			table.insert(rets, vo)
		end
		self:_sortFriends(rets)
		app:sendMsg("FriendController", "updateSearchList", rets)
	end
	return rets
end

----------------------------------------- request ------------------------------------
function ClassRef:reqRecommendFriend(cb) -- 拉取推荐/搜索玩家
	app.session:request("pb_friend.C2S_RecommendFriend", {}, function(ret)
		-- dump(ret, "FriendModel:reqRecommendFriend() ret")
		self._recommendTime = app:getTime() -- 保存时间戳
		if ret.users then
			self._recommends = self:updateSearch(ret.users)
		else
			self._recommends = {}
			display.pushToast(L("tips_3000293"))
		end
		executeFunc(cb)
	end)
end

function ClassRef:reqSearchNearbyUser() -- 拉取附近好友
	-- 接口关闭了，使用地图上附近的角色
	-- app.session:request("pb_friend.C2S_SearchNearbyUser", {}, function(ret)
	-- dump(ret, "FriendModel:reqSearchNearbyUser() ret")
	-- 	self._nearTime = app:getTime() -- 保存时间戳
	-- 	if ret.users then
	-- 		self._nears = self:updateSearch(ret.users)
	-- 	else
	-- 		display.pushToast(L("tips_1040022"))
	-- 	end
	-- end)
end

--key = UID/name
function ClassRef:reqLocateUser(key)
	app.session:request("pb_friend.C2S_LocateUser", {keyword=tostring(key)}, function(ret)
		-- dump(ret, "FriendModel:reqLocateUser() ret")
		if ret.users and #ret.users > 0 then
			self:updateSearch(ret.users)
		else
			display.pushToast(L("ErrNobodyMatch"))
		end
	end)
end

-- 请求添加好友
function ClassRef:reqAddFriendByUID(uid)
	if UD:isFriend(uid) then
		app:popMessage("alreadyfriend", {pushToast=true})
		return
	end

	app.session:request("pb_friend.C2S_SendFriendRequest", {uid = uid}, function(ret)
		if ret and ret.ok then
			display.pushToast( L("lua_code_text_299") )
		else
			display.pushToast( L("lua_code_text_518") )
		end
	end)
end

function ClassRef:reqRemoveFriendByUID(uid)
	app.session:request("pb_friend.C2S_RemoveFriendByUID", {uid=uid}, function(ret)
		-- dump(ret, "FriendModel:reqRemoveFriendByUID() ret")
		EM:notify("onRemoveFriend", {ret.name})
		display.pushToast(string.format(L("deletefriend"), ret.name))
	end)
end

--key = UID/name
function ClassRef:reqAddBlacklist(key, cb)
	app.session:request("pb_friend.C2S_AddBlacklist", {keyword=tostring(key)}, function(ret)
		-- dump(ret, "FriendModel:reqAddBlacklist() ret")
		if ret.ok then
			EM:notify("onAddBlack", {ret.name})
			display.pushToast(string.format(L("tips_1060003"), ret.name))
			executeFunc(cb)
		end
	end)
end
--key = UID/name
function ClassRef:reqRemoveBlacklist(key)
	app.session:request("pb_friend.C2S_RemoveBlacklist", {keyword=tostring(key)}, function(ret)
		-- dump(ret, "FriendModel:reqRemoveBlacklist() ret")
		if ret.ok then
			EM:notify("onRemoveBlack", {ret.name})
			display.pushToast(string.format(L("tips_1060004"), ret.name))
		end
	end)
end

-- 获取好友的最新状态
function ClassRef:reqFriendsStatus(cb)
	app.session:request("pb_friend.C2S_FriendStatusList", {}, function(ret)
		-- dump(ret, "FriendModel:C2S_FriendStatusList() ret", 10)
		if ret.users then
			local dict = {}
			for i,v in ipairs(ret.users) do
				dict[v.userBaseInfo.uid] = v
			end

			for i,vo in ipairs(self._friends) do
				local uid = vo.uid
				if dict[uid] then
					vo:read(dict[uid])
				end
			end
			self:_sortFriends(self._friends)
		end
		executeFunc(cb)
	end)
end

function ClassRef:reqRecentList(cb)
	if self._recents then
		executeFunc(cb)
		return
	end

	app.session:request("pb_friend.C2S_RecentTeamMemberList", {}, function(ret)
		-- dump(ret, "FriendModel.C2S_RecentTeamMemberList")
		if ret.users and #ret.users > 0 then
			self._recents = {}
			for i,v in ipairs(ret.users) do
				local vo = Friend.new(v, Enums.FriendType.stranger)
				self._recents[#self._recents + 1] = vo
			end

			self:_sortFriends(self._recents)

			app:sendMsg("FriendController", "updateRecentList")
			app:sendMsg("NewTeamApplyController", "updateRecentInvitList")
		end
		executeFunc(cb)
	end)
end

-- 拉取好友申请列表
function ClassRef:reqFriendRequestList(cb)
	if self._requests then
		executeFunc(cb)
		return
	end

	app.session:request("pb_friend.C2S_FriendRequestList", {}, function(ret)
		self._requests = {}
		if ret.users and #ret.users > 0 then
			for _, v in ipairs(ret.users) do
				local vo = Friend.new(v, Enums.FriendType.apply)
				table.insert(self._requests, vo)
			end
		end
		-- dump(self._requests)
		executeFunc(cb)
	end)
end

-- 处理好友申请信息
function ClassRef:handlerFriendRequest(uid, name, agree)
	app.session:request("pb_friend.C2S_HandleFriendRequest", {uid = uid, agree = agree}, function(ret)
		if ret and ret.ok then
			self:removeFriendRequest(uid)
			app:sendMsg("FriendController", "upadteRequestList")

			if agree then 
				display.pushToast(string.format(L("tips_1060002"), name))
				EM:notify("onAddFriend", {name})
			end
		else
			display.pushToast( L("lua_code_text_418") )
		end
	end)
end


return ClassRef
